//
//  BZThemeModel.m
//  MZBasic
//
//  Created by Sings on 2022/8/10.
//

#import "BZThemeModel.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "UIColor+BZTheme.h"
#import "UIImage+BZTheme.h"


static NSString * const _kColorThemeDataSel = @"BZTheme_colorWithKey:";
static NSString * const _kImageNameThemeDataSel = @"BZTheme_imageNameWithKey:";

static NSString * const _kBlockKeyPath = @"##BZTHEME_KEYPATH_BLOCK##@";
static NSString * const _kSelKeyPath = @"##BZTHEME_KEYPATH_SEL##";


static BZ_INLINE void _ThemeUpdate(id target, NSString *strSel,  id arg) {
//    va_list params;
//    va_start(params,strSel);
    SEL sel = NSSelectorFromString(strSel);
    if (arg == nil) {
        ((void (*)(id, SEL))(void *) objc_msgSend)((id)target, sel);
    }else {
        ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)target, sel,arg);
    }
    
}

static BZ_INLINE const void *_ThemeData(id target, NSString *strSel, __unsafe_unretained NSString *arg) {
//    va_list params;
//    va_start(params,strSel);
    SEL sel = NSSelectorFromString(strSel);
    if (arg == nil) {
        return ((void * (*)(id, SEL))(void *) objc_msgSend)((id)target, sel);
    }else {
        return ((void * (*)(id, SEL, id))(void *) objc_msgSend)((id)target, sel, arg);
    }
    
}

static BZ_INLINE NSString *_keyPathSetter(NSString *keyPath) {
    return [NSString stringWithFormat:@"set%@%@:", [keyPath substringToIndex:1].uppercaseString, [keyPath substringFromIndex:1]];
}

@interface BZThemeModel ()
@property (nonatomic, copy) NSString *keyPathSel;
@property (nonatomic, copy) NSString *themeDataSel;

@property (nonatomic, weak, readwrite) id target;

@property (nonatomic, copy, readwrite) NSString *key;

@property (nonatomic, copy, readwrite) NSString *keyPath;

@property (nonatomic, assign, readwrite) BZThemeModelType type;

@property (nonatomic, copy, readwrite) BZThemeBindBlock themeBlock;

@end

@implementation BZThemeModel

- (instancetype) initColorWithTarget:(id) target KeyPath:(NSString *) keyPath ColorKey:(NSString *) key {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = keyPath;
        self.keyPathSel = _keyPathSetter(keyPath);
        self.key = key;
        self.type = BZThemeModelType_Color;
        self.themeDataSel = _kColorThemeDataSel;
    }
    return self;
}

- (instancetype) initColorWithTarget:(id) target KeyPath:(NSString *) keyPath ColorPath:(NSString *) colorPath {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = keyPath;
        self.keyPathSel = _keyPathSetter(keyPath);
        self.key = nil;
        self.type = BZThemeModelType_Color;
        self.themeDataSel = colorPath;
        if (![UIColor respondsToSelector:NSSelectorFromString(colorPath)]) {
            self.themeDataSel = _kColorThemeDataSel;
            self.key = colorPath;
        }
    }
    return self;
}

- (instancetype) initCGColorWithTarget:(id) target KeyPath:(NSString *) keyPath ColorKey:(NSString *) key {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = keyPath;
        self.keyPathSel = _keyPathSetter(keyPath);
        self.key = key;
        self.type = BZThemeModelType_CGColor;
        self.themeDataSel = _kColorThemeDataSel;
    }
    return self;
}

- (instancetype) initCGColorWithTarget:(id) target KeyPath:(NSString *) keyPath ColorPath:(NSString *) colorPath {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = keyPath;
        self.keyPathSel = _keyPathSetter(keyPath);
        self.key = nil;
        self.type = BZThemeModelType_CGColor;
        self.themeDataSel = colorPath;
        if (![UIColor respondsToSelector:NSSelectorFromString(colorPath)]) {
            self.themeDataSel = _kColorThemeDataSel;
            self.key = colorPath;
        }
    }
    return self;
}

- (instancetype) initBlockWithTarget:(id) target Block:(BZThemeBindBlock) block {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = _kBlockKeyPath;
        self.themeBlock = block;
        self.type = BZThemeModelType_Block;
    }
    return self;
}

- (instancetype) initSelWithTarget:(id) target Sel:(SEL) sel {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = _kSelKeyPath;
        self.keyPathSel = NSStringFromSelector(sel);
        self.type = BZThemeModelType_Sel;
    }
    return self;
}

- (instancetype) initImageWithTarget:(id) target KeyPath:(NSString *) keyPath ImageKey:(NSString *) key {
    if (self = [super init]) {
        self.target = target;
        self.keyPath = keyPath;
        self.keyPathSel = _keyPathSetter(keyPath);
        self.key = nil;
        self.type = BZThemeModelType_Image;
        self.themeDataSel = key;
        if (![UIImage respondsToSelector:NSSelectorFromString(key)]) {
            self.themeDataSel = _kImageNameThemeDataSel;
            self.key = key;
        }
    }
    return self;
}

- (void) refresh {
//    __weak typeof(self) weakSelf = self;
//    dispatch_async(dispatch_get_main_queue(), ^{
        [self _refresh];
//    });
}

- (void) _refresh {
    switch (self.type) {
        case BZThemeModelType_Color:
        {
            _ThemeUpdate(self.target,self.keyPathSel, (__bridge UIColor*)_ThemeData([UIColor class], self.themeDataSel,self.key));
        }
            break;
        case BZThemeModelType_CGColor:
        {
            _ThemeUpdate(self.target,self.keyPathSel, ((__bridge UIColor*)_ThemeData([UIColor class], self.themeDataSel,self.key)).CGColor);
        }
            break;
        case BZThemeModelType_Image:
            _ThemeUpdate(self.target,self.keyPathSel, (__bridge UIImage*)_ThemeData([UIImage class], self.themeDataSel,self.key));
            break;
        case BZThemeModelType_Block:
        {
            if (self.themeBlock) {
                self.themeBlock();
            }
        }
            break;
        case  BZThemeModelType_Sel:
        {
            SEL sel = NSSelectorFromString(self.keyPathSel);
            if ([self.target respondsToSelector:sel]) {
                _ThemeUpdate(self.target,self.keyPathSel,nil);
            }
        }
            break;
        default:
            break;
    }
}

- (void)dealloc {
//    NSLog(@"------------ThemeModel----%lu",(unsigned long)self.type);
}

@end
